package com.tool.main;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.tool.bean.QBOGenInfo;
import com.tool.bean.TableGenInfo;
import com.tool.util.ConfigUtil;
import com.tool.util.StringUtil;
import com.tool.util.TemplateUtil;

import freemarker.template.Template;

public class CodeGen
{
	
	private static transient Log log = LogFactory.getLog(CodeGen.class);
	
	public static void main(String[] args)
		throws Exception
	{
		File dir = new File("D:/auto");
		List files = new ArrayList();
		getFile(dir, files);
		for (int i = 0; i < files.size(); i++)
		{
			File file = (File) files.get(i);
			gen(file);
		}
	}
	
	public static void start(TableGenInfo info)
		throws Exception
	{
		gen(info);
	}
	
	private static void getFile(File file, List files)
		throws Exception
	{
		if (file.isDirectory())
		{
			File[] fs = file.listFiles();
			for (int i = 0; i < fs.length; i++)
			{
				getFile(fs[i], files);
			}
			
		}
		else if (file.getName().endsWith(".xml"))
		{
			files.add(file);
		}
	}
	
	public static void start(QBOGenInfo info)
		throws Exception
	{
		Map result = QBOReader.getParams(info);
		
		if (log.isDebugEnabled())
		{
			log.debug("------------------------------------");
			log.debug("处理表:" + info);
			log.debug("获取参数:" + result);
			log.debug("------------------------------------");
		}
		
		String beanName = (String) result.get("Bean");
		String packageName = (String) result.get("package");
		
		File srcDir = new File(ConfigUtil.getProperty("src"));
		String packagePath = packageName.replaceAll("\\.", "/");
		File packageDir = new File(srcDir, packagePath + "/");
		if (!packageDir.exists())
		{
			packageDir.mkdirs();
		}
		
		File beanDir = new File(packageDir, "bean/");
		if (!beanDir.exists())
		{
			beanDir.mkdir();
		}
		Template ftlBean = TemplateUtil.getTemplate("qbean.ftl");
		Writer beanWriter = new OutputStreamWriter(new FileOutputStream(
				new File(beanDir, beanName + ".java")),
				Charset.forName("UTF-8"));
		ftlBean.process(result, beanWriter);
		beanWriter.close();
		
		File daoDir = new File(packageDir, "dao/");
		if (!daoDir.exists())
		{
			daoDir.mkdir();
		}
		Template ftlDAO = TemplateUtil.getTemplate("qdao.ftl");
		Writer daoWriter = new OutputStreamWriter(new FileOutputStream(
				new File(daoDir, beanName + "DAO.java")),
				Charset.forName("UTF-8"));
		ftlDAO.process(result, daoWriter);
		daoWriter.close();
		
		File configDir = new File(ConfigUtil.getProperty("config"));
		if (!configDir.exists())
		{
			configDir.mkdirs();
		}
		File dsDir = new File(configDir, info.getDsName());
		if (!dsDir.exists())
		{
			dsDir.mkdir();
		}
		Template ftlMapper = TemplateUtil.getTemplate("qmapper.ftl");
		Writer mapperWriter = new FileWriter(new File(dsDir, beanName
				+ "DAOMapper.xml"));
		ftlMapper.process(result, mapperWriter);
		mapperWriter.close();
	}
	
	private static void gen(TableGenInfo info)
		throws Exception
	{
		Map result = DbReader.getParams(info);
		
		if (log.isDebugEnabled())
		{
			log.debug("------------------------------------");
			log.debug("处理表:" + info);
			log.debug("获取参数:" + result);
			log.debug("------------------------------------");
		}
		
		String beanName = (String) result.get("Bean");
		String packageName = (String) result.get("package");
		String entityTable = (String) result.get("entityTable");
		entityTable = entityTable.toLowerCase();
		result.put("beanname", StringUtil.getCamel(beanName));
		
		String[] controllers = entityTable.split("_");
		String controller = entityTable;
		if (controllers.length != 1)
		{
			controller = "";
			for (String c : controllers)
			{
				controller += "/" + c;
			}
		}
		
		result.put("controller", controller);
		File srcDir = new File(ConfigUtil.getProperty("src"));
		File jspDir = new File(ConfigUtil.getProperty("jsp"));
		File jsDir = new File(ConfigUtil.getProperty("js"));
		
		String packagePath = packageName.replaceAll("\\.", "/");
		File packageDir = new File(srcDir, packagePath + "/");
		if (!packageDir.exists())
		{
			packageDir.mkdirs();
		}
		
		if (!jspDir.exists())
		{
			jspDir.mkdirs();
		}
		
		if (!jsDir.exists())
		{
			jsDir.mkdirs();
		}
		
		File beanDir = new File(packageDir, "bean/");
		if (!beanDir.exists())
		{
			beanDir.mkdir();
		}
		Template ftlBean = TemplateUtil.getTemplate("bean.ftl");
		Writer beanWriter = new OutputStreamWriter(new FileOutputStream(
				new File(beanDir, beanName + ".java")),
				Charset.forName("UTF-8"));
		ftlBean.process(result, beanWriter);
		beanWriter.close();
		
		File daoDir = new File(packageDir, "dao/");
		if (!daoDir.exists())
		{
			daoDir.mkdir();
		}
		Template ftlDAO = TemplateUtil.getTemplate("dao.ftl");
		Writer daoWriter = new OutputStreamWriter(new FileOutputStream(
				new File(daoDir, beanName + "DAO.java")),
				Charset.forName("UTF-8"));
		ftlDAO.process(result, daoWriter);
		daoWriter.close();
		
		File configDir = new File(ConfigUtil.getProperty("config"));
		if (!configDir.exists())
		{
			configDir.mkdirs();
		}
		File dsDir = new File(configDir, info.getDsName());
		if (!dsDir.exists())
		{
			dsDir.mkdir();
		}
		Template ftlMapper = TemplateUtil.getTemplate("mapper.ftl");
		Writer mapperWriter = new FileWriter(new File(dsDir, beanName
				+ "DAOMapper.xml"));
		ftlMapper.process(result, mapperWriter);
		mapperWriter.close();
		
		if ("true".equalsIgnoreCase(info.getAutoGenSV()))
		{
			File serviceDir = new File(packageDir, "service/");
			if (!serviceDir.exists())
			{
				serviceDir.mkdir();
			}
			File serviceImplDir = new File(packageDir, "service/impl/");
			if (!serviceImplDir.exists())
			{
				serviceImplDir.mkdir();
			}
			Template ftlService = TemplateUtil.getTemplate("service.ftl");
			Template ftlServiceImpl = TemplateUtil
					.getTemplate("serviceImpl.ftl");
			
			Writer serviceWriter = new OutputStreamWriter(new FileOutputStream(
					new File(serviceDir, 'I' + beanName + "SV.java")),
					Charset.forName("UTF-8"));
			ftlService.process(result, serviceWriter);
			serviceWriter.close();
			
			Writer serviceImplWriter = new OutputStreamWriter(
					new FileOutputStream(new File(serviceImplDir, beanName
							+ "SVImpl.java")), Charset.forName("UTF-8"));
			ftlServiceImpl.process(result, serviceImplWriter);
			serviceImplWriter.close();
			
			/** 创建controller */
			File controllerDir = new File(packageDir, "controller/");
			if (!controllerDir.exists())
			{
				controllerDir.mkdir();
			}
			Template ftlController = TemplateUtil.getTemplate("controller.ftl");
			
			Writer controllerWriter = new OutputStreamWriter(
					new FileOutputStream(new File(controllerDir, beanName
							+ "Controller.java")), Charset.forName("UTF-8"));
			ftlController.process(result, controllerWriter);
			controllerWriter.close();
			
			/** 创建Views */
			File viewDir = new File(jspDir, StringUtil.getCamel(beanName) + "/");
			if (!viewDir.exists())
			{
				viewDir.mkdir();
			}
			
			Template ftlJspIndex = TemplateUtil.getTemplate("index.ftl");
			
			Template ftlJspInfo = TemplateUtil.getTemplate("info.ftl");
			
			Writer jspIndexWriter = new OutputStreamWriter(
					new FileOutputStream(new File(viewDir, "index.jsp")),
					Charset.forName("UTF-8"));
			ftlJspIndex.process(result, jspIndexWriter);
			jspIndexWriter.close();
			
			Writer jspInfoWriter = new OutputStreamWriter(new FileOutputStream(
					new File(viewDir, "info.jsp")), Charset.forName("UTF-8"));
			ftlJspInfo.process(result, jspInfoWriter);
			jspInfoWriter.close();
			
			/** 创建js */
			File jsHomeDir = new File(jsDir, StringUtil.getCamel(beanName)
					+ "/");
			if (!jsHomeDir.exists())
			{
				jsHomeDir.mkdir();
			}
			Template ftlJs = TemplateUtil.getTemplate("js.ftl");
			
			Writer jsWriter = new OutputStreamWriter(
					new FileOutputStream(new File(jsHomeDir,
							StringUtil.getCamel(beanName) + ".js")),
					Charset.forName("UTF-8"));
			ftlJs.process(result, jsWriter);
			jsWriter.close();
		}
	}
	
	private static void gen(File file)
		throws Exception
	{
		System.out.println("Generate File : " + file.getName());
		InputStream is = null;
		Map result = null;
		try
		{
			is = new FileInputStream(file);
			result = XmlReader.getParams(is);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (is != null)
			{
				is.close();
			}
		}
		
		String beanName = (String) result.get("Bean");
		String packageName = (String) result.get("package");
		
		File srcDir = new File(ConfigUtil.getProperty("src"));
		String packagePath = packageName.replaceAll("\\.", "/");
		File packageDir = new File(srcDir, packagePath + "/");
		if (!packageDir.exists())
		{
			packageDir.mkdirs();
		}
		File beanDir = new File(packageDir, "bean/");
		if (!beanDir.exists())
		{
			beanDir.mkdir();
		}
		Template ftlBean = TemplateUtil.getTemplate("bean.ftl");
		Writer beanWriter = new FileWriter(
				new File(beanDir, beanName + ".java"));
		ftlBean.process(result, beanWriter);
		beanWriter.close();
		
		File daoDir = new File(packageDir, "dao/");
		if (!daoDir.exists())
		{
			daoDir.mkdir();
		}
		Template ftlDAO = TemplateUtil.getTemplate("dao.ftl");
		Writer daoWriter = new FileWriter(new File(daoDir, beanName
				+ "DAO.java"));
		ftlDAO.process(result, daoWriter);
		daoWriter.close();
		Template ftlMapper = TemplateUtil.getTemplate("mapper.ftl");
		Writer mapperWriter = new FileWriter(new File(daoDir, beanName
				+ "DAOMapper.xml"));
		ftlMapper.process(result, mapperWriter);
		mapperWriter.close();
		
		if ("true".equalsIgnoreCase(ConfigUtil.getProperty("generate-service")))
		{
			File serviceDir = new File(packageDir, "service/");
			if (!serviceDir.exists())
			{
				serviceDir.mkdir();
			}
			File serviceImplDir = new File(packageDir, "service/impl/");
			if (!serviceImplDir.exists())
			{
				serviceImplDir.mkdir();
			}
			Template ftlService = TemplateUtil.getTemplate("service.ftl");
			Template ftlServiceImpl = TemplateUtil
					.getTemplate("serviceImpl.ftl");
			
			Writer serviceWriter = new FileWriter(new File(serviceDir, 'I'
					+ beanName + "SV.java"));
			ftlService.process(result, serviceWriter);
			serviceWriter.close();
			
			Writer serviceImplWriter = new FileWriter(new File(serviceImplDir,
					beanName + "SVImpl.java"));
			ftlServiceImpl.process(result, serviceImplWriter);
			serviceImplWriter.close();
		}
	}
}
